﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace GrayParrot.Infrastructure.Menu
{
    public class MenuManager : DataAccessBase
    {
        private List<MenuItem> m_data = null;

        public MenuManager()
        {

        }

        public MenuManager(Settings settings) : base(settings)
        {

        }

        //private void GetRoots()
        //{
        //    using (MenuEntities ctx = new MenuEntities(this.Settings.ConnectionStringName))
        //    {
        //        var objs = from x in ctx.Menu where x.ParentId == null orderby x.MenuIndex select x;

        //        if (objs.Any())
        //        {

        //        }
        //    }
        //}

        //private void GetChilds(Guid root)
        //{
        //    using (MenuEntities ctx = new MenuEntities())
        //    {
        //        var objs = from x in ctx.Menu where x.ParentId == root select x;

        //        if (objs.Any())
        //        {
        //            var ppp = objs.Select(x => x.Menu1);
        //        }
        //    }
        //}

        //private void GetData(Guid parent)
        //{
        //    using (MenuEntities ctx = new MenuEntities())
        //    {
        //        var objs = from x in ctx.Menu where x.ParentId == parent orderby x.MenuIndex select x;

        //        if (objs.Any())
        //        {
 
        //        }
        //    }
        //}

        public List<MenuItem> Load()
        {
            List<MenuItem> retValue = null;

            try
            {
                using (MenuEntities ctx = new MenuEntities(this.Settings.ConnectionStringName))
                {
                    var objs = from x in ctx.Menu
                               where x.IsActive.Value
                               orderby x.MenuIndex
                               select new MenuItem()
                               {
                                   MenuId = x.MenuId,
                                   Name = x.Name,
                                   ParentId = x.ParentId,
                                   Controller = x.Controller,
                                   IconPath = x.IconPath,
                                   Index = (x.MenuIndex.HasValue ? x.MenuIndex.Value : byte.MinValue),
                                   Url = x.Url,
                                   Tooltip = x.Tooltip
                               };

                    if (objs.Any())
                    {
                        retValue = ConvertListToTree(objs.ToList());

                        m_data = retValue;
                    }
                }
            }
            catch (System.Reflection.ReflectionTypeLoadException ex)
            {
                Console.WriteLine(ex.Message);
                foreach (var loaderEx in ex.LoaderExceptions) Console.WriteLine(loaderEx.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return retValue;
        }

        private List<MenuItem> ConvertListToTree(List<MenuItem> flatList)
        {
            var rootNodes = new List<MenuItem>();
            foreach (var node in flatList)
            {
                //The parent of this node in the flat list (if there is one).
                var parent = flatList.Find(i => i.MenuId == node.ParentId);
                if (parent == null)
                {
                    //Collect the root nodes to return later...
                    rootNodes.Add(node);
                }
                else
                {
                    //Ignore orphans (should never happen, but just in case)...
                    if (!flatList.Exists(i => i.MenuId == node.ParentId))
                        continue;

                    //add this node to the child list of its parent.
                    if (parent.Childs == null)
                        parent.Childs = new List<MenuItem>();
                    parent.Childs.Add(node);
                }
            }
            return rootNodes;
        }

        public string GetJsonizedMenu()
        {
            string retValue = string.Empty;

            List<MenuItem> children = (m_data != null ? m_data : this.Load());

            JsonSerializerSettings settings = new JsonSerializerSettings
            {
                Converters = new List<JsonConverter> { new NodeConverter() },
                Formatting = Formatting.Indented,
            };

            var p = new { success = true, children };

            retValue = JsonConvert.SerializeObject(p, settings);

            return retValue;
        }

        public string ToULTag()
        {
            string retValue = string.Empty;

            List<MenuItem> data = (m_data != null ? m_data : this.Load());

            StringBuilder sb = new StringBuilder();

            //sb.Append("<div class=\"navigationRoot\">");
            sb.Append("<ul class=\"childsContainer\">");
            foreach(MenuItem item in data)
            {
                sb.Append(CreateChildTags(item));
            }
            sb.Append("</ul>");
            //sb.Append("</div>");
            retValue = sb.ToString();

            return retValue;
        }

        private string CreateChildTags(MenuItem item)
        {
            string retValue = string.Empty;

            string m_class = (((item.Childs != null) && (item.Childs.Count > 0)) ? (item.Index == 0 ? "menuRoot" : "subMenuRoot") : "");

            //retValue += string.Format("<li class=\"{0}\"><a href=\"{1}\" data-toggle=\"dropdown\">{2}</a>",
            //                                            m_class,
            //                                            item.Url, 
            //                                            item.Name);
            if ((item.Childs != null) && (item.Childs.Count > 0))
            {
                retValue += string.Format("<li class=\"{0}\"><a href=\"{1}\" data-toggle=\"dropdown\">{2}</a>",
                                            m_class,
                                            item.Url,
                                            item.Name);

                retValue += "<ul class=\"menu\">";
                foreach (MenuItem childItem in item.Childs)
                {

                    retValue += CreateChildTags(childItem);

                }

                retValue += "</ul>";
            }
            else
            {
                retValue += string.Format("<li><a href=\"{0}\">{1}</a>", item.Url, item.Name);
            }

            retValue += "</li>";

            return retValue;
        }

        private string CreateChildTags__(MenuItem item)
        {
            string retValue = string.Empty;

            if ((item.Childs != null) && (item.Childs.Count > 0))
            {
                retValue += string.Format("<li class=\"{0}\"><a href=\"{1}\" data-toggle=\"dropdown\">{2}</a>", (item.Index == 0 ? "menuRoot" : "subMenuRoot"), item.Url, item.Name);
                foreach (MenuItem childItem in item.Childs)
                {
                    if ((childItem.Childs != null) && (childItem.Childs.Count > 0))
                    {
                        retValue += string.Format("<ul class=\"menu\">");
                        retValue += CreateChildTags(childItem);
                        retValue += string.Format("</ul>");
                    }
                    else
                    {
                        retValue += CreateChildTags(childItem);
                    }
                }
                retValue += string.Format("</li>");
            }
            else
            {
                retValue += string.Format("<li><a href=\"{0}\">{1}</a></li>", item.Url, item.Name);
            }
            
            return retValue;
        }
    }
}
